package cscie160.hw5;
import java.util.HashMap;
import java.util.ArrayList;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
 * This class is the actual ATM.
 * that has a reference to an instance of a class Account and manipulates its balance.
 * <BR>An instance of ATMImpl will run on the server. 
 * @author Michael Melnikov 
*/
public class ATMImpl extends UnicastRemoteObject implements ATM {
    private HashMap <Integer, Account> accounts; 

    /**
    * no-args constructor creates ATM with no accounts
    */   
    public ATMImpl() throws RemoteException{
        super();
    }
 
    /**
    * 1-arg constructor creates ATM with single account with balance equal to its argument
    * @param balance int
    */   
    public ATMImpl(int balance) throws ATMException, RemoteException{
        this(new ArrayList<Integer>(java.util.Arrays.asList(new Integer[]{new Integer(balance)})));
    }   
    
    /**
    * 1-arg constructor creates ATM with few accounts.
    * Accounts have balances equal to values
     * of ArrayList passed as constructor argument
    * @param balances ArrayList<Integer> 
    */   
    public ATMImpl(ArrayList<Integer> balances) throws ATMException, RemoteException{
        super();
        if (balances == null || balances.size() == 0)
            throw new ATMException("no balances provided.");        
        accounts = new HashMap<Integer, Account>();
        
        for (int balanceNum = 0; balanceNum < balances.size(); balanceNum++){
            int accountNum = accounts.size() + Account.minAccountNumber;
            Account account = new Account(accountNum);
            accounts.put(accountNum, account);
            deposit(accountNum, balances.get(balanceNum));
        }
    }     
    
    /**
    * deposits sum equal to its argument to the account
    * @param accountNumber int    
    * @param amount int
    */
    public void deposit(int accountNumber, int amount) throws ATMException, RemoteException{
        Account account = accounts.get(accountNumber);
        if (account == null)
            throw new ATMException(getClass().getName() + ".deposit(): account with ID=" +
                accountNumber + " doesn't exist.");
        account.deposit(amount);
    }
    
    /**
    * withdraws sum equal to its argument off the account
    * @param accountNumber int    
    * @param amount int    
    */    
    public void withdraw(int accountNumber, int amount) throws ATMException, RemoteException{
        Account account = getAccount(accountNumber);    
        if (account == null)
            throw new ATMException(getClass().getName() + ".withdraw(): account with ID=" +
                accountNumber + " doesn't exist.");
        account.withdraw(amount);    
    }
    
    /**
    * returns balance of the account.
    * @param accountNumber int
    * @return int
    */
    public int getBalance(int accountNumber) throws ATMException, RemoteException{
        Account account = getAccount(accountNumber);    
        if (account == null)
            throw new ATMException(getClass().getName() + ".getBalance(): account with ID=" +
                accountNumber + " doesn't exist.");
        return account.getBalance();
    }
    
    /**
    * returns Account by its integer id
    * @param accountNumber int      
    * @return cscie160.hw5.Account    
    */    
    private Account getAccount(int accountNumber){
        if (!accounts.containsKey(accountNumber))
            return null;
        Account account = accounts.get(accountNumber);     
        return account;
    }
}
